#include "header.h"

#define GSIZE(o) (sizeof(int) + sizeof(t_som)*(o))
#define room(g,s) (g->lsom[(s)])
#define succ(g,s) (room(g,s)->succ)
#define pred(g,s) (room(g,s)->pred)
#define next(p) ((p)=(p)->next)

#define MAX 1000

typedef struct s_graph *t_graph;
typedef struct s_som   *t_som;
typedef struct s_adj   *t_adj;

struct s_som
{
  int som;
  int cost;
  t_adj succ, pred;
};
 
struct s_adj
{
  float cost;
  int vsom;
  t_adj next;
};
 
struct s_graph
{
  int order;
  t_som lsom[1];
};

t_graph create_graph(int order)
{
  t_graph g;
  int i;
  g = malloc(GSIZE(order));
  g->order = order;
  for (i=0; i<order; i++)
    {
      room(g,i) = malloc(sizeof(struct s_som));
      room(g,i)->som = i+1;
      room(g,i)->cost = 0;
      succ(g,i) = pred(g,i) = NULL;
    }
  return g;
}
 
void add_arc(t_graph g, int s, int d, float c)
{
  t_adj pa;
  pa = malloc(sizeof(struct s_adj));
  pa->cost = c;
  pa->vsom = d;
  pa->next = succ(g,s);
  succ(g,s) = pa;
  pa = malloc(sizeof(struct s_adj));
  pa->cost = c;
  pa->vsom = s;
  pa->next = pred(g,d);
  pred(g,d) = pa;
}

void set_cost(t_graph g, int s, int cost)
{
  int i = 0;
  while(room(g,i)->som != s)
    {
      i++;
    }
  room(g,i)->cost = cost;
}

t_graph read_file(FILE *file)
{
  t_graph g;
  int i;
  int j;
  int fst;
  int rooms;
  int sec;
  int ter;
  char str[MAX] = "";
  char temp[20] = "";

while(fgets(str, MAX, file) != NULL)
  {
    if(str[0] != '#' && str[0] != '\n')
      {
	if(str[0] == 'R')
	  {
	    i = 7;
	    while(str[i] != '\0')
	      {
		temp[i-7] = str[i];
		i++;
	      }
	    rooms = atoi(temp);
	    g = create_graph(rooms);
	  }
	
	if(str[0] == 'M')
	  {
	    i = 9;
	    memset(temp, 0, sizeof(temp));
	    while(str[i] != ' ')
	      {
		temp[i-9] = str[i];
		i++;
	      }
	    fst = atoi(temp);		  
	    i++;
	    j = i;
	    memset(temp, 0, sizeof(temp));
	    while(str[i] != '\0')
	      {
		temp[i-j] = str[i];
		i++;
	      }
	    sec = atoi(temp);
	    set_cost(g,fst,-sec);
	  }
	
	if(str[0] == 'B')
	  {
	    i = 9;
	    memset(temp, 0, sizeof(temp));
	    while(str[i] != ' ')
	      {
		temp[i-9] = str[i];
		i++;
	      }
	    fst = atoi(temp);
	    i++;
	    j = i;
	    memset(temp, 0, sizeof(temp));
	    while(str[i] != '\0')
	      {
		temp[i-j] = str[i];
		i++;
	      }
	    sec = atoi(temp);
	    set_cost(g,fst,sec);
	  }
	
	if(str[0] == 'D')
	  {
	    i = 6;
	    memset(temp, 0, sizeof(temp));
	    while(str[i] != '\0')
	      {
		temp[i-6] = str[i];
		i++;
	      }
	    fst = atoi(temp);
	  }
	
	if(str[0] == 'A' && str[3] == ':')
	  {
	    i = 5;
	    memset(temp, 0, sizeof(temp));
	    while(str[i] != ' ')
	      {
		temp[i-5] = str[i];
		i++;
	      }
	    fst = atoi(temp);
	    i++;
	    j = i;
	    memset(temp, 0, sizeof(temp));
	    while(str[i] != ' ')
	      {
		temp[i-j] = str[i];
		i++;
	      }
	    sec = atoi(temp);
	    i++;
	    j = i;
	    memset(temp, 0, sizeof(temp));
	    while(str[i] != '\0')
	      {
		temp[i-j] = str[i];
		i++;
	      }
	    ter = atoi(temp);
	    add_arc(g,fst-1,ter-1,sec);
	  }
      }
  }
 return g;
}

void dijk(t_graph g, int source, int ppd[], int pr[])
{
  int i = 0;
  int y; 
  int m;
  int v;
  int M[MAX];

  while (i != g->order)
    {
      ppd[i] = get_cost(source, i, g); /* FONCTION A FAIRE */
      pr[i] = source;
      M[i] = i;
      i++;
    }
  M[source] = -1337;   /* Supprimer(x,M) */
  while (!(is_empty(M)))    /* FONCTION A FAIRE */
    {
      m = get_min(M,ppd); /* FONCTION A FAIRE */
      if(ppd[m] == -1337)
	return;
      M[m] = -1337;
      i = 0;
      while(i != demi_deg(m,g))  /* FONCTION A FAIRE */
	{
	  y = ieme_succ(i,m,g); /* FONCTION A  FAIRE */
	  if(is_in_g(y,g))    /* FONCTION A FAIRE */
	    {
	      v = ppd[m] + get_cost(m,y,g);
	      if(v < ppd[y])
		{
		  ppd[y] = v;
		  pr[y] = m;
		}
	    }
	}
    }
}

void Cost(t_graph g, int life, char* path)
{
  int ppd[MAX];
  int pr[MAX];

  dijk(g, 0, ppd,pr);

  /* TRAITEMENT DE LA VIE ET PATH */
}

int main(int argc, char* argv[])
{
  FILE *file = NULL;
  t_graph g;

  if(argc <= 1)
    {
      printf("Erreur, pas de parametres.\n");
      exit(1);
    }
  else
    {
      file = fopen(argv[1],"r");
      
      if(file == NULL)
	{
	  printf("Erreur d'ouverture du fichier.\n");
	  exit(1);
	}
      
      g = read_file(file);
      
      free(g);
      fclose(file);
    }
  return 0;
}
